package com.sh3h.generator.web.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mysql.cj.util.StringUtils;
import com.sh3h.generator.entity.Constant;
import com.sh3h.generator.utils.ConfigUtil;
import com.sh3h.generator.utils.DateUtils;
import com.sh3h.generator.utils.StringUtil;
import com.sh3h.generator.utils.TemplateUtils;
import com.sh3h.generator.web.domain.*;
import com.sh3h.generator.web.dtos.GenCodeDto;
import com.sh3h.generator.web.service.IGenService;
import freemarker.cache.StringTemplateLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.rmi.ServerException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream;

@Service
public class GenServiceImpl implements IGenService {
    @Autowired
    private GenTableServiceImpl genTableService;
    @Autowired
    private GenTableFieldServiceImpl genTableFieldService;
    @Autowired
    private GenFtlServiceImpl genFtlService;
    @Autowired
    private GenFieldTypeServiceImpl genFieldTypeService;

    @Override
    public void downloadCode(Long tableId, ZipOutputStream zip) {

    }

    @Override
    public void generatorCode(Long tableId, GenCodeDto dto) {
// 数据模型
        Map<String, Object> dataModel = getTemplateModalData(tableId);
        dataModel.put("package", dto.getPackageName());
        dataModel.put("moduleName", dto.getModuleName());
        dataModel.put("functionName", dto.getFunctionName());
        dataModel.put("author", dto.getAuthor());
        dataModel.put("email", dto.getEmail());
        dataModel.put("version", dto.getVersion());
        List<GenFtl> genFtlList = genFtlService.list();
        String content = "";
        // 渲染模板并输出
        for (GenFtl template : genFtlList) {
            dataModel.put("templateName", FileUtil.getName(template.getFtlName()));
            try {
                content = TemplateUtils.getContent(template.getFtlData(), dataModel);
            } catch (ServerException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            String _package = FileUtil.getName(template.getFtlName()).split("\\.")[0];
            String path = dto.getBackendPath() + "/src/main/java/" + dto.getPackageName().replace(".", File.separator) + "/" + dto.getModuleName() + "/" + _package.toLowerCase() + "/" + dataModel.get("ClassName") + StrUtil.upperFirst(_package) + ".java";
            if (template.getFtlName().toLowerCase().contains("serviceimpl")) {
                path = dto.getBackendPath() + "/src/main/java/" + dto.getPackageName().replace(".", File.separator) + "/" + dto.getModuleName() + "/service/impl/" + dataModel.get("ClassName") + StrUtil.upperFirst(_package) + ".java";
            }
            FileUtil.writeUtf8String(content, path);
        }
    }

    private Map<String, Object> getTemplateModalData(Long tableId) {
        GenTable genTable = genTableService.getById(tableId);
        LambdaQueryWrapper<GenTableField> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GenTableField::getTableId, tableId);
        List<GenTableField> tableFieldList = genTableFieldService.list(queryWrapper);
        List<GenTableField> queryFieldList = tableFieldList.stream().filter(a -> a.getQueryItem() == 1).collect(Collectors.toList());
        List<GenFieldType> fieldTypeList = genFieldTypeService.list();
        List<String> importList = fieldTypeList.stream().filter(a -> StrUtil.isNotBlank(a.getPackageName())).map(GenFieldType::getPackageName).collect(Collectors.toList());
        Map<String, Object> objectMap = new HashMap<>();

        objectMap.put("Configuration", ConfigUtil.getConfiguration());
        objectMap.put("tableName", genTable.getTableName());
        objectMap.put("tableComment", genTable.getTableComment());
        objectMap.put("className", StrUtil.lowerFirst(genTable.getClassName()));
        objectMap.put("ClassName", StrUtil.upperFirst(genTable.getClassName()));
        objectMap.put("dateTime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
        objectMap.put("date", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
        objectMap.put("fieldList", tableFieldList);
        objectMap.put("queryList", queryFieldList);
        objectMap.put("importList", importList);
        return objectMap;
    }
}
